package com.app;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.text.StyleContext.SmallAttributeSet;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import com.checkfree.isolutions.customer.persist.Account;
import com.checkfree.isolutions.customer.persist.AccountHomeImpl;
import com.checkfree.isolutions.customer.persist.Merchant;
import com.checkfree.isolutions.customer.persist.MerchantHomeImpl;
import com.checkfree.isolutions.persist.PersistServer;
import com.checkfree.isolutions.statement.StatementSection;
import com.checkfree.isolutions.statement.persist.Statement;
import com.checkfree.isolutions.statement.persist.StatementHomeImpl;
import com.dao.Bill;
import com.dao.BillSummary;
import com.dao.CurrentBillCharges;
import com.dao.RewardSummary;

public class HtmlGenerator {
	
	public static final String MERCHANT = "ASTRO";
	
	public static final String CONFIG_FILE = "/properties/HtmlGenerator.properties";
	public static final java.util.Properties appConfig =  new java.util.Properties();
	
	public HtmlGenerator() {
		try {
			InputStream stream = this.getClass().getResourceAsStream(
					CONFIG_FILE);
			if (stream != null) {
				appConfig.load(stream);
			} else {
				throw new Exception("input stream is null");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
    public static void main( String[] args ) throws Throwable {
    	System.out.println("start Html Generator");
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		
    	String accountNo = "89048937";
    	String stmtDateStr = "20140918";
    	Date statementDate = formatter.parse(stmtDateStr);
    	
    	try {
    		
        	HtmlGenerator htmlGen = new HtmlGenerator();
        	
    		PersistServer.activate(MERCHANT);
    		PersistServer.beginTransaction();
    		
    		Statement statement = null;
    		Merchant theMerchant = MerchantHomeImpl.singleton().findByName(MERCHANT);
    		if (theMerchant == null) {
    			throw new Exception("unable to obtain Persist Merchant object");
    		}
    		Account account = AccountHomeImpl.singleton()
    						.findByExternalKeyAndMerchant(accountNo, theMerchant);
   
    		if (account != null) {
    			statement = StatementHomeImpl.singleton().findByAccountAndDate(account, statementDate);
    		
    			htmlGen.putdata(statement);

    		}

    	
		}catch (Exception ex){
			throw ex;
		} finally {
			PersistServer.deactivate();
		}
    	System.out.println("Html Generator end");

    	
    }
    public void putdata (Statement stmt) throws Exception{
    	
    	VelocityEngine ve = new VelocityEngine();
        ve.init();
        Template t = ve.getTemplate( "./src/index.html" );
        VelocityContext context = new VelocityContext();
        
    	BillSummary billsum = setDataToBillSummary(stmt);
        
    	//put data to customer information
    	context.put("name", billsum.getAccountName());
    	context.put("addList", billsum.getAddList());
    	context.put("accountNumber", billsum.getAccountNumber());
    	context.put("stmtDate", new SimpleDateFormat("dd/MM/yyyy").format(stmt.getDate()));
    	context.put("month", new SimpleDateFormat("MMM yyyy").format(stmt.getDate()));
    	context.put("billingPeriod", billsum.getBillPeriod());
    	
        //put data to Your last bill

        context.put("previousbalance", billsum.getPreviousMontBalance());
        context.put("payment", billsum.getPayment());
        context.put("adjustments", billsum.getAdjustments());
        
        //put data to Your current bill
        
        context.put("overduecharges", billsum.getOverdueCharges());
        context.put("newCharges", billsum.getNewCharged());
        context.put("amountdue", billsum.getAmountDue());
        
        
        // put data to pay Date
        context.put("paydate", billsum.getPayDate());
        


        CurrentBillCharges transaction = setDataToTransactionDetails(stmt);
        context.put("transaction", transaction);
        context.put("transcationTotal", transaction.getTotal());
        
        //put data to Current Bill Charges
        List<CurrentBillCharges> currentBillList = setDataToCurrentBill(stmt);
        context.put("currentBillList", currentBillList);

        
        //put data to tax and total
        context.put("tax", billsum.getTax());
        context.put("totalcharge", billsum.getTotalCharges());
        
        /*****************************GenChart**************************************/
        List<CurrentBillCharges> genChartList = new ArrayList<>();
        genChartList.add(transaction);
        for(int i =0;i<currentBillList.size();i++){
        	genChartList.add(currentBillList.get(i));
        }
        clearString(genChartList);
        context.put("genChartList", genChartList);
        /*******************************************************************************/
        
        
        
        // Start Put data for Reward
        RewardSummary rewardSum = setDataToRewardSummary(stmt);
        
//        rewardSum.setExpiryMonth("May 2015");
//        rewardSum.setExpiryPoints("20");
//        rewardSum.setPointsEarned("11");
//        rewardSum.setPointsRedeemed("20");
//        rewardSum.setPreviousBalance("300");
//        rewardSum.setTotalNewBalance("200");
        
        context.put("rewardSum", rewardSum);
        // End Put data for Reward
        
        
        StringWriter writer = new StringWriter();
        t.merge( context, writer );
        
        BufferedWriter bwrite = null;
        try {
			
//	        File file = new File("D:/astro/astro 2/index_output.html");
	        
	        File file = new File(appConfig.getProperty("html.path"));
	        bwrite = new BufferedWriter(new FileWriter(file, false));
	        bwrite.write(writer.toString());
	        System.out.println("finish write file to "+appConfig.getProperty("html.path")  );

        } catch (Exception e) {
        	e.printStackTrace();
        } finally {
        	bwrite.close();
        }
    }
    
    public BillSummary setDataToBillSummary(Statement stmt){

    	BillSummary billsum = new BillSummary();

    	StatementSection cfiRootSection = stmt.getRootSection();
    	

    	
    	StatementSection transactionDetailsSection = cfiRootSection.getSection("TransactionDetailsSection");
    	
    	/***********************get data***********************************/
    	
    	//get data for customer information
    	String accountName = cfiRootSection.getFieldText("AccountName");
    	
    	StatementSection addressSection = cfiRootSection.getSection("AddressSection");
    	int addressSectionCount = (int)addressSection.getSectionCount("RepeatSection");
    	List<String> addList = new ArrayList<>();
    	for(int i=0;i<addressSectionCount;i++){
    		StatementSection repeatSection = addressSection.getRepeatSection("RepeatSection", i);
    		addList.add(repeatSection.getFieldText("Address"));
    	}
    	String accountNumber = cfiRootSection.getFieldText("FullAccNo");
    	String billPeriod = cfiRootSection.getFieldText("BillingPeriod");
    	
    	//get data for last bill
    	String prevMonthBalance 	= cfiRootSection.getFieldText("PrevMonthBalance");
		String payment = cfiRootSection.getFieldText("Payment");
		String adjustments 	= cfiRootSection.getFieldText("Adjustments");

		
		//get data for current bill
		String overDueAmt 	= cfiRootSection.getFieldText("OverDueAmt");
    	String amountCharged = cfiRootSection.getFieldText("NewCharges"); // confirm (amount charged)
		String amountDue 	= cfiRootSection.getFieldText("AmountDue");

    	
    	//get data for transaction

    	String dueDate 	= cfiRootSection.getFieldText("DueDate"); // Confirm
    	
    	//get data for Government Service Tax 
    	StatementSection serviceTaxSection = transactionDetailsSection.getSection("ServiceTaxSection");
    	String serviceTax = serviceTaxSection.getFieldText("Total"); //Confirm
    	
    	StatementSection totalChargesSection = transactionDetailsSection.getSection("TotalChargesSection");
    	String totalCharge = totalChargesSection.getFieldText("Total");

    	/******************** set data ***********************************/   	
    	//customer information
    	billsum.setAccountName(accountName);
    	billsum.setAddList(addList);
    	billsum.setAccountNumber(accountNumber);
    	billsum.setBillPeriod(billPeriod);
    	
    	//Your last bill
    	billsum.setPreviousMontBalance(prevMonthBalance);
    	billsum.setAdjustments(adjustments);
    	billsum.setPayment(payment);
//    	billsum.setOverdueAmount(overDueAmt);
    	
    	//Your current bill
    	
    	billsum.setOverdueCharges(overDueAmt);
    	billsum.setNewCharged(amountCharged);
    	billsum.setAmountDue(amountDue);
    	
    	//transaction


    	
        billsum.setPayDate(dueDate);
        billsum.setTax(serviceTax);
        
        billsum.setTotalCharges(totalCharge);
        
    	return billsum;
    }


    public RewardSummary setDataToRewardSummary(Statement stmt){

    	RewardSummary rewardSum = new RewardSummary();

    	StatementSection cfiRootSection = stmt.getRootSection();
    	
    	StatementSection loyaltyPointSection = cfiRootSection.getSection("LoyaltyPointSection");
		if(loyaltyPointSection!=null){
			
			rewardSum.setPreviousBalance(loyaltyPointSection.getFieldText("PreviousBalance"));
			rewardSum.setPointsEarned(loyaltyPointSection.getFieldText("PointsEarned"));
			rewardSum.setPointsRedeemed(loyaltyPointSection.getFieldText("PointsRedeemed"));
			rewardSum.setTotalNewBalance(loyaltyPointSection.getFieldText("TotalNewBalance"));
			rewardSum.setExpiryMonth(loyaltyPointSection.getFieldText("ExpiryMonth"));
			rewardSum.setExpiryPoints(loyaltyPointSection.getFieldText("ExpiryPoints"));
		}

		
    	return rewardSum;
    }

    
    public List<CurrentBillCharges> setDataToCurrentBill (Statement stmt){
    	StatementSection cfiRootSection = stmt.getRootSection();
    	StatementSection transactionDetailsSection = cfiRootSection.getSection("TransactionDetailsSection");
    	StatementSection currentBillChargesSection = transactionDetailsSection.getSection("CurrentBillChargesSection");
    	int smartCardRSectionCount = (int)currentBillChargesSection.getSectionCount("SmartCardRSection");
    	List<CurrentBillCharges> currentBillList = new ArrayList<>();
    	for(int i=0;i<smartCardRSectionCount;i++){
    		CurrentBillCharges curtBillCharge = new CurrentBillCharges();
    		
    		StatementSection smartCardRSection = currentBillChargesSection.getRepeatSection("SmartCardRSection", i);
    		curtBillCharge.setSmartCardNo(smartCardRSection.getFieldText("SmartCardNo"));
    		int repeatSectionCount = (int)smartCardRSection.getSectionCount("RepeatSection");
    		List<Bill> billList = new ArrayList<>();
    		float totalBillCharges = 0;
    		for(int j=0; j<repeatSectionCount;j++){
    			StatementSection repeatSection = smartCardRSection.getRepeatSection("RepeatSection", j);
    			Bill bill = new Bill();
    			bill.setDescription(repeatSection.getFieldText("Description"));
    			bill.setAmount(repeatSection.getFieldText("Amount"));
    			bill.setPeriod(repeatSection.getFieldText("Period"));
    			String total = repeatSection.getFieldText("Total");
    			totalBillCharges = totalBillCharges + convertToInt(repeatSection.getFieldText("Amount"));
    			if(repeatSection.getFieldText("Description").isEmpty()){
    				break;
				
				}
    			billList.add(bill);
    		}
    		curtBillCharge.setTotal(String.valueOf(totalBillCharges));
    		curtBillCharge.setBillLst(billList);
    		currentBillList.add(curtBillCharge);
    	}
    	
    	return currentBillList;
    }
    public CurrentBillCharges setDataToTransactionDetails(Statement stmt){
    	CurrentBillCharges transaction = new CurrentBillCharges();
    	StatementSection cfiRootSection = stmt.getRootSection();
    	StatementSection transactionDetailsSection = cfiRootSection.getSection("TransactionDetailsSection");
    	StatementSection overdueChargesSection = transactionDetailsSection.getSection("OverdueChargesSection");

    	transaction.setTotal(overdueChargesSection.getFieldText("Total"));
    	transaction.setSmartCardNo("Previous month balance");
    	
    	StatementSection summarySection = transactionDetailsSection.getSection("SummarySection");
    	int repeatSectionCount = (int)summarySection.getSectionCount("RepeatSection");
    	List<Bill> billList = new ArrayList<>();
    	for (int i = 0;i<repeatSectionCount;i++){
    		Bill bill = new Bill();
    		StatementSection repeatSection = summarySection.getRepeatSection("RepeatSection", i);
    		bill.setDescription(repeatSection.getFieldText("Description"));
    		bill.setAmount(repeatSection.getFieldText("Amount"));
			bill.setPeriod(repeatSection.getFieldText("Period"));
			bill.setTotal(repeatSection.getFieldText("Total"));
			billList.add(bill);
    	}
    	transaction.setBillLst(billList);
    	return transaction;
    }
    public float convertToInt(String string){
    	string.replaceAll(" ", "");
    	float number=0;
    	if(!string.isEmpty()){
    		number = Float.parseFloat(string);
    	}

    	return number;
    }
    public void clearString(List<CurrentBillCharges> chargeList){
    	for(int i=0;i<chargeList.size();i++){
    		chargeList.get(i).setTotal(removeJunkString(chargeList.get(i).getTotal()));
    		for(int j =0; j<chargeList.get(i).getBillLst().size();j++){
    			chargeList.get(i).getBillLst().get(j).setAmount(removeJunkString(chargeList.get(i).getBillLst().get(j).getAmount()));
    			chargeList.get(i).getBillLst().get(j).setTotal(removeJunkString(chargeList.get(i).getBillLst().get(j).getTotal()));
    		}
    	}
    }
    public String removeJunkString (String string){ 
    	if(!StringUtils.isEmpty(string)){
    		string= string.replaceAll("-", "");
    		string= string.replaceAll(",", "");
    		return string;
    	}
    	else{
    			return"";
    }}
}